package com.slipper.system.dictionary.controller;

import java.lang.reflect.Type;
import java.util.*;

import com.google.gson.reflect.TypeToken;
import com.slipper.constants.Constants;
import com.slipper.core.cache.CacheKey;
import com.slipper.core.cache.CacheUtil;
import com.slipper.core.tree.TreeInfo;
import com.slipper.core.tree.TreeUtil;
import com.slipper.util.ResultUtil;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.slipper.system.dictionary.bo.DictionaryBO;
import com.slipper.system.dictionary.bo.DictionaryDataBO;
import com.slipper.system.dictionary.service.DictionaryDataService;
import com.slipper.system.dictionary.service.DictionaryService;

@RestController
@RequestMapping("/system/dictionary")
public class DictionaryController {

    @Resource
    private DictionaryService dictionaryService;
    @Resource
    private DictionaryDataService dictionaryDataService;


    @PostMapping("/queryBy")
    public String queryBy(@RequestBody DictionaryBO bo) {
        return ResultUtil.successResult(dictionaryService.queryBy(bo.getId()));
    }

    @PostMapping("/queryList")
    public String queryList(@RequestBody DictionaryBO bo) {
        return ResultUtil.successResult(dictionaryService.queryList(bo));
    }

    @PostMapping("/queryPage")
    public String queryPage(@RequestBody DictionaryBO bo) {
        return ResultUtil.successResult(dictionaryService.queryPage(bo));
    }

    @PostMapping("/queryTree")
    public String queryTree() {
        List<DictionaryBO> list = dictionaryService.queryList(new DictionaryBO());
        TreeInfo treeInfo = new TreeInfo("字典树");
        treeInfo.setRootId(Constants.ROOT_ID);
        treeInfo.setIdField("id");
        treeInfo.setPidField("parentId");
        treeInfo.setTextField("name");
        return ResultUtil.successResult(TreeUtil.buildTree(treeInfo, list));
    }

    @PostMapping("/save")
    public String save(@RequestBody DictionaryBO bo) {
        if (bo.getParentId() == null) {
            bo.setParentId(Constants.ROOT_ID);
        }
        return ResultUtil.saveResult(dictionaryService.save(bo), bo);
    }

    @PostMapping("/delete")
    public String delete(@RequestBody DictionaryBO bo) {
        String[] ids = null;
        if (bo.getIds() != null) {
            ids = bo.getIds();
        } else if (bo.getId() != null) {
            ids = new String[] { bo.getId() };
        }
        if (ids == null) {
            return ResultUtil.failureResult("参数不正确！");
        }
        for (String id : ids) {
            DictionaryBO qo = new DictionaryBO();
            qo.setParentId(id);
            if (!this.dictionaryService.queryList(qo).isEmpty()) {
                qo.setId(id);
                qo.setParentId(null);
                return ResultUtil.failureResult(
                        "字典[" + this.dictionaryService.queryBy(qo.getId()).getName() + "]其下有子字典，不允许删除！");
            }

            DictionaryDataBO dataQo = new DictionaryDataBO();
            dataQo.setDictId(id);
            if (!this.dictionaryDataService.queryList(dataQo).isEmpty()) {
                qo.setId(id);
                qo.setParentId(null);
                return ResultUtil.failureResult(
                        "字典[" + this.dictionaryService.queryBy(qo.getId()).getName() + "]其下有字典数据，不允许删除！");
            }
        }
        return ResultUtil.deleteResult(dictionaryService.delete(bo));
    }

    @PostMapping("/queryAllDicData")
    public String queryAllDicData() {
        Type type = new TypeToken<Map<String, List<Map<String, String>>>>(){}.getType();
        Map<String, List<Map<String, String>>> resultMap = CacheUtil.get(CacheKey.Dictionary.KEY, type);
        if (resultMap == null) {
            List<DictionaryDataBO> list = this.dictionaryDataService.queryList(new DictionaryDataBO());
            Map<String, List<Map<String, String>>> finalMap = new HashMap<>();
            list.forEach(bo -> {
                List<Map<String, String>> result = finalMap.computeIfAbsent(bo.getDictId(), k -> new LinkedList<>());
                Map<String, String> data = new HashMap<>();
                data.put("pid", bo.getDictParent());
                data.put("key", bo.getDictKey());
                data.put("value", bo.getDictValue());
                data.put("ordinal", String.valueOf(bo.getOrdinal()));
                result.add(data);
            });
            resultMap = finalMap;
            CacheUtil.set(CacheKey.Dictionary.KEY, resultMap, 60 * 60);
        }
        return ResultUtil.successResult(resultMap);
    }

}
